package modelz.ui;

import java.awt.Component;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import modelz.Updateable;
import modelz.UpdateableCollection;
import modelz.UpdateableCollectionListener;

public class PeerMap<S extends Updateable<S>,T extends Peer<S,? extends Component>> implements UpdateableCollectionListener<S> {

	private final Map<S,T> peers = new HashMap<S,T>();
	private final Class<T> peerClass;
	private final PeerFactory client;
	private final List<PeerMapListener<T>> listeners = new CopyOnWriteArrayList<PeerMapListener<T>>();
	
	public PeerMap(PeerFactory client, UpdateableCollection<S> map, Class<T> peerClass) {
		this.client = client;
		this.peerClass = peerClass;
		map.addListener(this);
	}

	public void added(S item) {
		try {
			T peer = client.createPeer(peerClass, item);
			peers.put(item, peer);
			for( PeerMapListener<T> listener : listeners )
				listener.itemAdded(peer);
		} catch( Exception e ) {
			throw new RuntimeException(e);
		}
	}

	public void removed(S item) {
		T peer = peers.get(item);
		peers.remove(item);
		if( peer != null )
			for( PeerMapListener<T> listener : listeners )
				listener.itemRemoved(peer);
	}
	
	public void cleared() {
		for( Iterator<T> i = peers.values().iterator(); i.hasNext(); ) {
			T peer = i.next();
			i.remove();
			for( PeerMapListener<T> listener : listeners )
				listener.itemRemoved(peer);			
		}
	}

	public void addListener(PeerMapListener<T> listener) {
		listeners.add(listener);
		for( T peer : peers.values() )
			listener.itemAdded(peer);
	}
	
	public void removeListener(PeerMapListener<T> listener) {
		listeners.remove(listener);
	}
	
	public T get(S item) {
		return peers.get(item);
	}

}
